package com.timber.util;

import java.util.Vector;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 *   Base class to extract and hold rows of data from database. Creates objects
 * based on the value of <b>className</b> constructor parameter.
 * All objects must extend SLDataObject and implement the following:
 * <pre
 *	hashKey() method. Used to build byHashKey map
 *	load( ResultSet ) method to read row data
 *	getId()	optional method returns long id. used to load byIdHash when buildIdHash is true
 * </pre>
 *
 * Database requests are directed to PRIMARY as default.
 * When BizDay( <b>setBizDate(java.util.Date d)<\b> ) is set to before ApplicationDate, requests are directed to
 * HISTORICAL server.
 * Otherwise logical dataserverName is used when set( <b>setDataserverName( String s )<\b> )
 *
 *   Stored Procedure name is the second argument.
 *
 *   Stored Proc parameters are stored in a Vector of Objects and SQL
 *   statement generated before execution of runProc().
 *
 *   runProc( Vector params ) method is available.
 *
 * Data can be sorted by setting Comparator( standard Java object ).
 *
 * keyVector and displayVector are not filled until first request unless lazyInit is
 * turned off.
 *
 * extending class can implement postLoad() method called after data is loaded
 *
 *	extends SLDataChangeListenerMgr to manage listner objects
 *
 */
public class SLDataMgr extends SLDataRecordsMgr implements Cancelable
{

  protected DBWaitDialog	dbWaitDialog;

  /**
   *	@param className class name of object to hold
   *	@param sql	initial sql statement
   */
  public SLDataMgr( String className, String sql )
  {
    this( className, sql, 100, 100 );
  }

  /**
   *	@param className class name of object to hold
   *	@param sql	initial sql statement
   *	@param initCap	initial capacity
   *	@param capInc	capacity increment
   */
  public SLDataMgr( String className, String sql, int initCap, int capInc )
  {
    super( className, sql, initCap, capInc );
  }

  /**
   *	@param className class name of object to hold
   *	@param sql	initial sql statement
   */
  public SLDataMgr( String className, String sql, boolean buildIdHash )
  {
    super( className, sql, buildIdHash );
  }

  /**
   *	@param sql	initial sql statement
   *	create data manager to load and hold a list of String codes, and
   *	optional Descriptions
   *	( e.i. SLDataStringPair objects ).
   */
  public SLDataMgr( String sql )
  {
    this( null, sql, 100, 100 );
  }

  /**
   *	copy constructor
   */
  public SLDataMgr( SLDataMgr aDM )
  {
    super( aDM );
  }


  public Vector runProcAsync( Vector params )
  {
    return runProcAsync( params, Global.getMainFrame() );
  }

  public Vector runProcAsync( Vector params, JFrame parent )
  {
    setProcParams(params);

    return runProcAsync( parent );
  }

  public Vector runProcAsync( Vector params, JDialog parent )
  {
	  setProcParams(params);

    return runProcAsync( parent );
  }

  public Vector initAsync()
  {
    return initAsync( Global.getMainFrame() );
  }

  /**
   *	display "Wait" dialog box and execute sql asynchronously
   *
   *	@param JFrame parent
   */
  public Vector initAsync( JFrame parent )
  {
    dbWaitDialog = new DBWaitDialog( parent,
				     this,
				     new SwingWorker()
				     {
				       public Object construct()
				       {
					 try
					 {
					   init();
					 }
					 catch( Exception ex )
					 {
					   clear();
					 }

					 return dataVector;
				       }

				       public void finished()
				       {
					 if( dbWaitDialog != null )
					 {
					   dbWaitDialog.dispose();
					 }
				       }
				     } );

    Object o = dbWaitDialog.showDialog();

    Vector ret = ((o != null)? (Vector)o : new Vector());

    o = null;
    dbWaitDialog = null;

    return ret;
  }

  /**
   *	display "Wait" dialog box and execute sql asynchronously
   *
   *	@param JDialog parent
   */
  public Vector initAsync( JDialog parent )
  {
    dbWaitDialog = new DBWaitDialog( parent,
				     this,
				     new SwingWorker()
				     {
				       public Object construct()
				       {
					 try
					 {
					   init();
					 }
					 catch( Exception ex )
					 {
					   clear();
					 }

					 return dataVector;
				       }

				       public void finished()
				       {
					 if( dbWaitDialog != null )
					 {
					   dbWaitDialog.dispose();
					 }
				       }
				     } );

    Object o = dbWaitDialog.showDialog();

    Vector ret = ((o != null)? (Vector)o : new Vector());

    o = null;
    dbWaitDialog = null;

    return ret;
  }

  public Vector runProcAsync()
  {
    return runProcAsync( Global.getMainFrame() );
  }

  public Vector runProcAsync( JFrame parent )
  {
    dbWaitDialog = new DBWaitDialog( parent,
				     this,
				     new SwingWorker()
				     {
				       public Object construct()
				       {
					 try
					 {
					   runProc();
					 }
					 catch( Exception ex )
					 {
					   clear();
					 }

					 return dataVector;
				       }

				       public void finished()
				       {
					 if( dbWaitDialog != null )
					 {
					   dbWaitDialog.dispose();
					 }
				       }
				     } );

    Object o = dbWaitDialog.showDialog();

    Vector ret = ((o != null)? (Vector)o : new Vector());

    o = null;
    dbWaitDialog = null;

    return ret;
  }

  public Vector runProcAsync( JDialog parent )
  {
    dbWaitDialog = new DBWaitDialog( parent,
				     this,
				     new SwingWorker()
				     {
				       public Object construct()
				       {
					 try
					 {
					   runProc();
					 }
					 catch( Exception ex )
					 {
					   clear();
					 }

					 return dataVector;
				       }

				       public void finished()
				       {
					 if( dbWaitDialog != null )
					 {
					   dbWaitDialog.dispose();
					 }
				       }
				     } );

    Object o = dbWaitDialog.showDialog();

    Vector ret = ((o != null)? (Vector)o : new Vector());

    o = null;
    dbWaitDialog = null;

    return ret;
  }




  public void setDBWaitDialog( DBWaitDialog dbWaitDialog )
  {
    this.dbWaitDialog = dbWaitDialog;
  }

  protected void updateProgress( final String note )
  {
    if( dbWaitDialog == null )
      return;

    Runnable doUpdateProgress = new Runnable()
      {
	public void run()
	{
	  dbWaitDialog.setNote( note );
	}
      };
    SwingUtilities.invokeLater( doUpdateProgress );
  }

}
